/*
 * loginCH.java
 *
 * Created on July 16, 2008, 8:41 PM
 */
package chimera;

import java.awt.event.KeyEvent;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.UIManager;

import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;

/**
 *
 * @author  Ryan rmann@oswego.edu
 * @author  Denis dbarrett@oswego.edu
 */
public class loginCH extends javax.swing.JFrame
{

    /**
     * Global variables used throughout hte class.
     */
    ArrayList<String> loginList = new ArrayList<String>();
    XmlRpcClient client = null;
    String server_url = "";
    InetAddress addr = null;
    String clientURL = "";

    /** Creates new form login 
     *  Loads the GUI and initializes all parameters
     */
    public loginCH()
    {
        //Capture the current IP address the computer is running on.
        try
        {
            addr = InetAddress.getLocalHost();
        }
        catch (UnknownHostException ex)
        {
            Logger.getLogger(loginCH.class.getName()).log(Level.SEVERE, null, ex);
        }

        //Set the default look and feel to OS type.
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        /***************************
         * GUI loader, Generated code.
         */
        initComponents();
        setLocationRelativeTo(null);
        /***************************/      
        
        //Read the file of used addresses and load it into the GUI list.
        try
        {
            //try to open file if exists
            FileInputStream f_in = new FileInputStream("loginCH.data");
            ObjectInputStream obj_in = new ObjectInputStream(f_in);
            loginList = (ArrayList<String>) obj_in.readObject();
        }
        catch (Exception ex)
        {
            //If file not present load defaults to list.
            loginList.add("");
            loginList.add("localhost");
        }

        //add all items from arrayList to JComboBox to diplay in GUI.
        for (int i = 0; i < loginList.size(); i++)
        {
            jCBaddress.addItem(loginList.get(i));
        }


    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        loginWelcome = new javax.swing.JLabel();
        jlabelServer = new javax.swing.JLabel();
        jCBaddress = new javax.swing.JComboBox();
        loginCANCEL = new javax.swing.JButton();
        loginOK = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Chimera Login");
        setAlwaysOnTop(true);
        setResizable(false);

        jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        loginWelcome.setBackground(new java.awt.Color(255, 255, 255));
        loginWelcome.setText("Welcome to Chimera.  Enter server information below.");
        loginWelcome.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
        loginWelcome.setOpaque(true);

        jlabelServer.setText("Server Address:");

        jCBaddress.setEditable(true);
        jCBaddress.setToolTipText("Enter IP address or Host name.");
        jCBaddress.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCBaddressActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(loginWelcome, javax.swing.GroupLayout.DEFAULT_SIZE, 266, Short.MAX_VALUE)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jlabelServer)
                        .addGap(49, 49, 49)
                        .addComponent(jCBaddress, 0, 139, Short.MAX_VALUE)))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(loginWelcome)
                .addGap(27, 27, 27)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jlabelServer)
                    .addComponent(jCBaddress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(28, Short.MAX_VALUE))
        );

        loginCANCEL.setText("CLOSE");
        loginCANCEL.setToolTipText("Click here to close and terminate the program.");
        loginCANCEL.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                loginCANCELMouseClicked(evt);
            }
        });

        loginOK.setText("OK");
        loginOK.setToolTipText("Click here to continue.");
        loginOK.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                loginOKMouseClicked(evt);
            }
        });
        loginOK.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                loginOKKeyPressed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(loginOK, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(loginCANCEL, javax.swing.GroupLayout.PREFERRED_SIZE, 77, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(loginOK)
                    .addComponent(loginCANCEL))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
     * If Cancel button is clicked then exit and teminate the program.
     * @param evt MouseEvent
     */
    private void loginCANCELMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_loginCANCELMouseClicked
        System.exit(0);
    }//GEN-LAST:event_loginCANCELMouseClicked

    /**
     * If Login button is clicked then check URL and call loadmainWindow.
     * @param evt MouseEvent
     */
    private void loginOKMouseClicked(java.awt.event.MouseEvent evt)
    {
        try
        {
            //call method to load main GUI
            loadMainWindow();
        }
        catch (MalformedURLException ex)
        {
            //default login error message
            loginWelcome.setText("<html><p><font color=\"red\">Bad Address, please try again.</font></p></htnl>");
        }
    }

    /**
     * If Enter is pressed then check URL and call loadmainWindow.
     * @param evt KeyEvent
     */
    private void loginOKKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_loginOKKeyPressed
        int key = evt.getKeyCode();
        //check if ENTER button was pressed.
        if (key == KeyEvent.VK_ENTER)
        {
            try
            {
                //call method to load main GUI
                loadMainWindow();
            }
            catch (MalformedURLException ex)
            {
                //Default login error message.
                loginWelcome.setText("<html><p><font color=\"red\">Bad Address, please try again.</font></p></htnl>");
            }
        }
    }//GEN-LAST:event_loginOKKeyPressed

    /**
     * If Enter is pressed then check URL and call loadmainWindow.
     * @param evt
     */
private void jCBaddressActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCBaddressActionPerformed

    //Ensure the box was modified
    if (evt.getActionCommand().equals("comboBoxEdited"))
    {
        try
        {
            //call method to load main GUI
            loadMainWindow();
        }
        catch (MalformedURLException ex)
        {
            //Default login error message.
            loginWelcome.setText("<html><p><font color=\"red\">Bad Address, please try again.</font></p></htnl>");
        }
    }
}//GEN-LAST:event_jCBaddressActionPerformed

    /**
     * Write the list of used Addresses to a file.
     */
    private void writeList()
    {
        //Write the serialized object to file
        try
        {
            //do not add if list already contains URL
            String tempAdd = jCBaddress.getSelectedItem().toString();
            if (!loginList.contains(tempAdd))
            {
                loginList.add(tempAdd);
            }

            //Setup and write the file
            FileOutputStream f_out = new FileOutputStream("loginCH.data");
            ObjectOutputStream obj_out = new ObjectOutputStream(f_out);
            obj_out.writeObject(loginList);
        }
        catch (Exception ex)
        {
            //catch an IO issue here.
            ex.printStackTrace();
        }

    }

    /**
     * Load main DockingWindowCH GUI, test for the existance of Chimera running 
     * on the selected URL. Also initialize the client for XML-RPC transmission.
     * @throws java.net.MalformedURLException
     */
    private void loadMainWindow() throws MalformedURLException
    {
        try
        {
            //Create the URl string for connection
            clientURL = jCBaddress.getSelectedItem().toString();
            
            //Initialize the XML-RPC client
            XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
            config.setServerURL(new URL("http://" + clientURL + ":7667/RPC2"));
            client = new XmlRpcClient();
            client.setConfig(config);
            
            //Create and empty Object Array to pass into the XML client
            Object[] obj = new Object[]
            {
            };
            //Call method 'isAlive' to verify Chimera is running.
            //The method takes no parameters, but must still send Object Array
            Object ret = client.execute("Chimera.isAlive", obj);

            //write address to file if successful
            writeList();
            
            //Hide and dispose of the login GUI
            this.dispose();

            //Load the DockingWindowCh main GUI in own thread
            java.awt.EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    new DockingWindowCH(client, clientURL);
                }
            });
        }
        catch (Exception ex)
        {
            //Set login screen default error message if unable to connect.
            loginWelcome.setText("<html><p><font color=\"red\">Invalid Address or IP, please try again.</font></p></htnl>");
        }


    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[])
    {
        java.awt.EventQueue.invokeLater(new Runnable()
        {

            public void run()
            {
                new loginCH().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JComboBox jCBaddress;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JLabel jlabelServer;
    private javax.swing.JButton loginCANCEL;
    private javax.swing.JButton loginOK;
    private javax.swing.JLabel loginWelcome;
    // End of variables declaration//GEN-END:variables
}
